/**
 * 初始化表单数据
 * 根据表单的JSON描述生成初始状态的表单数据对象
 * @param {Object} formJson - 表单的JSON描述对象
 * @returns {Object} - 初始化后的表单数据对象
 */
export function initFormData(formJson) {
  // 创建并返回一个空的表单数据对象
  const formData = {};

  /**
   * 处理表单字段
   * 根据字段的类型递归地初始化表单数据结构
   * @param {Array} fields - 待处理的表单字段数组
   * @param {Object} parentData - 当前层级的表单数据对象
   */
  function processFields(fields, parentData) {
    // 遍历每个字段，根据其类型初始化相应的数据结构
    fields.forEach((field) => {
      // 如果是分组，则创建一个新的对象，并递归处理子字段
      if (field.componentName === 'group') {
        parentData[field.valueName] = {};
        processFields(field.fields, parentData[field.valueName]);
      } else {
        // 对于非分组字段，直接设置默认值
        if (field.defaultValue !== undefined) {
          parentData[field.valueName] = field.defaultValue;
        } else {
          parentData[field.valueName] = '';
        }
        // 对于日期选择器，如果选择的是月范围，则默认为空数组
        if (field.componentName === 'el-date-picker') {
          parentData[field.valueName] = [];
        } else if (field.componentName === 'el-table') {
          parentData[field.valueName] = [];
        }
      }
    });
  }

  // 开始处理表单JSON中的字段，最终填充到formData中
  processFields(formJson.fields, formData);
  // 返回初始化后的表单数据对象
  return formData;
}

/**
 * 根据表单结构和数据计算特定字段的值
 * 此函数通过解析表单结构中的计算项和计算结果项，并根据提供的数据进行计算，更新表单数据
 * @param {Object} formJson - 表单结构的JSON对象，包含字段的定义和计算规则
 * @param {Object} formData - 用户填写的表单数据，根据这些数据进行计算
 */
export function calculateFunction(formJson, formData) {
  // 创建一个Map对象来存储需要参与计算的项及其值
  const calculateItemMap = new Map();
  const statisticsItemMap = new Map();

  // 收集需要操作的项
  function createItemMap(fields, data) {
    fields.forEach((field) => {
      if (field.componentName === 'group') {
        createItemMap(field.fields, data[field.valueName]);
      } else {
        if (field.isCalculateItem) {
          calculateItemMap.set(field.valueName, data[field.valueName]);
        }
        if (field.isStatisticsItem) {
          statisticsItemMap.set(field.valueName, data[field.valueName]);
        }
      }
    });
  }

  // 根据计算规则计算结果
  function createResult(fields, data) {
    fields.forEach((field) => {
      if (field.componentName === 'group') {
        createResult(field.fields, data[field.valueName]);
      } else {
        if (field.isCalculateResult) {
          data[field.valueName] = calculateExpression(field.calculateExpression, calculateItemMap);
        }
        if (field.isCalculateTableResult) {
          data[field.valueName] = calculateItemMap
            .get(field.calculateExpression)
            .map((item) => item[field.calculateColumn])
            .reduce((acc, curr) => acc + Number(curr), 0)
            .toFixed(2);
        }
        if (field.isStatisticsTableResult) {
          let statisticsTable = statisticsItemMap.get(field.statisticsTable);
          data[field.valueName] = statisticsTable.filter(
            (item) => item[field.statisticsTableColumn] === field.label
          ).length;
        }
      }
    });
  }

  createItemMap(formJson.fields, formData);
  createResult(formJson.fields, formData);
}

/**
 * 计算给定表达式的值
 *
 * @param {string} expression - 待计算的数学表达式，可能包含变量
 * @param {Map} calculateItemMap - 变量及其对应值的映射表
 * @returns {number} - 计算结果，保留两位小数
 */
function calculateExpression(expression, calculateItemMap) {
  // 使用正则表达式匹配表达式中的变量名
  const variableRegex = /\b\w+\b/g;
  const variables = expression.match(variableRegex);
  // 遍历变量，替换为对应的值
  variables.forEach((variable) => {
    if (calculateItemMap.has(variable)) {
      let value = calculateItemMap.get(variable);
      // 如果值为空字符串，则将其替换为零
      if (value === '') {
        value = 0;
      }
      expression = expression.replace(variable, value);
    }
  });
  // 使用eval函数计算表达式的值，并保留两位小数
  const result = eval(expression);
  return parseFloat(result.toFixed(2));
}
